package com.dianrong.common.uniauth.server.datafilter.impl;

import java.lang.reflect.Field;

import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;

import com.dianrong.common.uniauth.common.bean.InfoName;
import com.dianrong.common.uniauth.common.util.StringUtil;
import com.dianrong.common.uniauth.server.datafilter.FieldType;
import com.dianrong.common.uniauth.server.datafilter.FilterData;
import com.dianrong.common.uniauth.server.datafilter.FilterType;
import com.dianrong.common.uniauth.server.exp.AppException;
import com.dianrong.common.uniauth.server.util.ObjectUtil;
import com.dianrong.common.uniauth.server.util.UniBundle;

import lombok.extern.slf4j.Slf4j;

/**
 * . 目前阶段需要处理的一个比较固定的流程
 * 
 * @author wanglin
 */
@Slf4j
public abstract class CurrentAbstractDataFilter<T> extends MultiTenancyCheck{
	@Override
	protected void doUpdateFieldsCheck(Integer id, FilterData... equalsField) {
		// 不处理
		if (equalsField == null || equalsField.length == 0) {
			return;
		}
		Object record = getEnableRecordByPrimaryKey(id);
		if (record != null) {
			// 默认是全部相等的
			boolean isEqual = true;
			// 如果数据信息没有改变 则不管
			for (FilterData fd : equalsField) {
				Object v1 = getObjectValue(record, fd.getType());
				Object v2 = fd.getValue();
				if (!ObjectUtil.objectEqual(v1, v2)) {
					isEqual = false;
					break;
				}
			}
			if (isEqual) {
				return;
			}
		}
		// 查看是否存在其他的记录是该信息
		this.addFieldsCheck(FilterType.FILTER_TYPE_EXSIT_DATA, equalsField);
	}

	@Override
	protected void doAddFieldsCheck(FilterType ftype, FilterData... equalsField) {
		// 不处理
		if (equalsField == null || equalsField.length == 0) {
			return;
		}
		Assert.notNull(ftype);
		switch (ftype) {
		case FILTER_TYPE_EXSIT_DATA:
			if (multiFieldsDuplicateCheck(equalsField)) {
				throw new AppException(InfoName.VALIDATE_FAIL, UniBundle.getMsg("datafilter.data.mutilcondition.exsit.error", 
						getProcessTableName(), getFieldTypeKeyAndValue(equalsField)));
			}
			break;
		case FILTER_TYPE_NO_DATA:
			if (!multiFieldsDuplicateCheck(equalsField)) {
				throw new AppException(InfoName.VALIDATE_FAIL, UniBundle.getMsg("datafilter.data.mutilcondition.notexsit.error", 
						getProcessTableName(), getFieldTypeKeyAndValue(equalsField)));
			}
			break;
		default:
			break;
		}
	}

	/**
	 * . 获取描述符
	 * 
	 * @param equalsField
	 *            equalsField处理的字段
	 * @return 描述符string
	 */
	private String getFieldTypeKeyAndValue(FilterData... equalsField) {
		if (equalsField == null || equalsField.length == 0) {
			return "";
		}
		StringBuilder sb = new StringBuilder();
		String filterKeyVal = "=";
		String filterEle = ";";
		for (FilterData fd : equalsField) {
			if (sb.toString().length() > 0) {
				sb.append(filterEle);
			}
			sb.append(fd.getType().getFieldName());
			sb.append(filterKeyVal);
			sb.append(StringUtil.getObjectStr(fd.getValue()));
		}
		return sb.toString();
	}

	/**
	 * . 从Role中获取数据
	 * 
	 * @param obj
	 *            Role
	 * @param type
	 *            结果
	 * @return 结果
	 */
	protected Object getObjectValue(Object obj, FieldType type) {
		if (obj == null) {
			return null;
		}
		try {
			if (type == null) {
				return null;
			}
			Field field = ReflectionUtils.findField(obj.getClass(), type.getFieldName());
			if (field == null) {
				return null;
			}
			field.setAccessible(true);
			// 通过反射获取值
			return ReflectionUtils.getField(field, obj);
		} catch (Exception ex) {
			log.warn("failed get object filed", ex);
		}
		return null;
	}

	/**
	 * . 处理查询数据中是否存在对应的字段相等的情况
	 * @param equalsField 字段列表,一定不为空
	 * @return 结果
	 */
	protected abstract boolean multiFieldsDuplicateCheck(FilterData... equalsField);

	/**
	 * . 获取描述的表的名字
	 * 
	 * @return 表名
	 */
	protected abstract String getProcessTableName();

	/**
	 * . 根据主键id获取一个启用状态的数据
	 * @param id primary key
	 * @return record
	 */
	protected abstract T getEnableRecordByPrimaryKey(Integer id);
}
